package com.erdos.common.util.excel;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import com.erdos.common.util.BeanUtils;

public class ExcelFormat {
	public static final String DEFAULT_PERCEN_FORMAT="0.00%";
	public static final String DEFAULT_COMMA_FORMAT="#,##0.00_);(#,##0.00)";
	public static final String DEFAULT_STRING_FORMAT="@";
	public static final String DEFAULT_INT_FORMAT="#,##0_);(#,##0)";
	public static final String DEFAULT_DOUBLE_FORMAT="###.00";

	
	private HSSFDataFormat dataFormat;
	private HSSFWorkbook wb;
	private Map styleMap;
	
	
	public ExcelFormat(HSSFWorkbook wb) {
		this.dataFormat=wb.createDataFormat();
		this.wb=wb;
		this.styleMap = new HashMap();
	}
	
	/**
	 * default decimal digits sets to 2.
	 * @param cell to be formatted HSSFCell
	 */
	public void setPercentFormat(HSSFCell cell) {
		cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);		
		
		short fmtIdx=0;
		if(2==0) {
			fmtIdx=HSSFDataFormat.getBuiltinFormat("0%");	
		} else if (2==2) {
			fmtIdx=HSSFDataFormat.getBuiltinFormat("0.00%");	
		} else {
			fmtIdx=this.dataFormat.getFormat("0." + this.getZeroFilledString(2) + "%");			
		}
		this.setCellFormat(cell, fmtIdx);;
	}
	
	/**
	 * default decimal digits sets to 2.
	 * @param cell to be formatted HSSFCell
	 */
	public void setCommaNumber(HSSFCell cell) {
		cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
		short fmtIdx=0;
		if(2==0) {
			fmtIdx=HSSFDataFormat.getBuiltinFormat("#,##0");	
		} else if(2==2) {
			fmtIdx=HSSFDataFormat.getBuiltinFormat("#,##0.00");	
		} else {
			fmtIdx=this.dataFormat.getFormat("#,##0." + this.getZeroFilledString(2));	
		}
		this.setCellFormat(cell, fmtIdx);
	}	
	
	public void setCellNumberFormat(HSSFCell cell, String format) {
		if(cell==null || HSSFCell.CELL_TYPE_NUMERIC !=cell.getCellType()) return;	
		
		short fmtIdx=this.dataFormat.getFormat(format);				
		setCellFormat(cell, fmtIdx);
	}

	private void setCellFormat(HSSFCell cell, short fmtIdx) {
		
		// get from Cache
		HSSFCellStyle tempStyle = (HSSFCellStyle)styleMap.get(getStyleKey(cell, fmtIdx));
		if(tempStyle != null){
			cell.setCellStyle(tempStyle);
		}
		else{
			HSSFCellStyle style = wb.createCellStyle(); 
			BeanUtils.copyProperties(style, cell.getCellStyle());	
			
	    	HSSFFont font = wb.createFont();
	    	BeanUtils.copyProperties(font,wb.getFontAt(cell.getCellStyle().getFontIndex()));
	    	
	    	style.setFont(font);
			style.setDataFormat(fmtIdx);	
			
			styleMap.put(getStyleKey(cell, fmtIdx), style);
			cell.setCellStyle(style);
		}
	}
	
	private String getStyleKey(HSSFCell cell, short dataFormat) {
		
		HSSFCellStyle style = cell.getCellStyle();
		HSSFFont font= wb.getFontAt(style.getFontIndex());
		
		// from ExcelWriter
		String fontName = font.getFontName();
		short fontColorIndex = font.getColor();
		short fillColor = style.getFillForegroundColor();
		int cellType = cell.getCellType();

		
		StringBuffer sb = new StringBuffer();
		sb.append(cellType).append("+");
		sb.append(fontName).append("+");
		sb.append(fontColorIndex).append("+");
		sb.append(fillColor).append("+");
		sb.append(dataFormat);
		return sb.toString();
	}

	private String getZeroFilledString(int len) {
		if(len<0) {
			len=Math.abs(len);
		}
		char [] suffix=new char[len];
		Arrays.fill(suffix, '0');
		return String.valueOf(suffix);
	}
}
